#!/bin/zsh

ENTRY="$2"
OPTION="$1"
DIR=$(printf "$2" | rev  | cut -d '/' -f2-9 | rev)


check_for_entry()
{
	if [ -z "$ENTRY" ]; then
		usage | less
		exit
	fi
}

edit()
{
	gpg -o ~/.spad"$ENTRY".ul -d ~/.spad"$ENTRY" 2>/dev/null
	nano ~/.spad/"$ENTRY".ul

	printf "\nOverwrite? [y/n] > "
	read -r OVERWRITE_FLAG
	case "$OVERWRITE_FLAG" in
		"Y" | "y")
			gpg --s2k-cipher-algo AES256 \
			  --s2k-digest-algo SHA512 \
			  --s2k-count 65011711 \
			  --symmetric ~/.spad"$ENTRY".ul 2>/dev/null
			mv ~/.spad/"$ENTRY".ul.gpg ~/.spad/"$ENTRY"
			rm ~/.spad/"$ENTRY".ul 2>/dev/null
			;;
		*)
			rm ~/.spad/"$ENTRY".ul 2>/dev/null
			printf "\nNot Overwriting...Exiting.\n"
			;;
esac
}

export_db()
{
	STAMP=$(date "+%Y-%m-%d_%H.%M.%S")
	EXP_NAME=$(printf "spad_$STAMP.zip")

	mkdir -p ~/.spad-archive/
	zip -rq ~/.spad-archive/."$EXP_NAME" ~/.spad/
	
	printf "Exported to /Users/$USER/.spad-archive/\n"
}

insert_test()
{
	if [ -f ~/.spad"$ENTRY" ]; then
		edit
	else
		insert
	fi
}

insert()
{
	mkdir -p ~/.spad/"$DIR"
	nano ~/.spad/"$ENTRY"
	gpg --s2k-cipher-algo AES256 \
		--s2k-digest-algo SHA512 \
		--s2k-count 65011711 \
		--symmetric ~/.spad"$ENTRY" 2>/dev/null
	mv ~/.spad"$ENTRY".gpg ~/.spad"$ENTRY" 2>~/.spad-errors/log.txt
}

remove()
{
	rm -rfv ~/.spad"$ENTRY"
}

show()
{
	if [ -z "$ENTRY" ]; then
		if [ ! -d ~/.spad ]; then
			printf "spad not initialized\n"
			exit
		fi

		tree ~/.spad | tail -r | tail -n +3 | tail -r
	else
		gpg -o ~/.spad"$ENTRY".ul -d ~/.spad"$ENTRY" 2>/dev/null
		less ~/.spad/"$ENTRY".ul 2>/dev/null
		rm ~/.spad/"$ENTRY".ul 2>/dev/null
	fi
}

usage()
{
	
	printf "spad
	
	NAME
		spad -- secure digital notepad and database
	
	SYNOPSISS
		spad [ COMMAND ] [ ARGS ]
	
	DESCRIPTION
		spad is a pass-inpsired, note-keeping utility that uses gpg encryption. spad 
		stores its database in the ~/.spad directory. Commands can be passed to 
		spad, giving the user the ability to edit, insert, and remove entries, 
		as well as the ability to export the database as a whole.
	
		Each entry is encrypted with its own user-given passphrase, each passphrase
		can be changed in the future. Entries are directories located in ~/.spad/.
		Entries can be removed individually, or the containing directory can be 
		recursively removed.
	
		spad also has backup functionality, allowing the user to export the current
		database to a .zip file. Each backup is timestamped and stored in the 
		~/.spad-archive/ directory. The .zip file backups are not encrypted, but 
		the original database remains encrypted. It is recommended to also manually
		encrypt the backup archives, preferably with a key or unique passphrase.
	
		The commands are case-insensitive.
		
	COMMANDS
		edit
			This allows the user to unlock an existing, encrypted entry and edit its
			contents.
		export
			This creates a backup of the current database containing all encrypted 
			entries located at ~/.spad/. Each backup is an unencrypted .zip file, 
			is timestamped by name, and is located at ~/.spad-archive/
		insert
			This creates an entry as well as given directories if the directories 
			do not exist.
		list
			If no specific directory is given, this lists all entries in the current
			database. If a specific directory is given, this lists all entries 
			within the specified directory.
		remove
			This removes entries and/or directories.
		show
			If no specific directory is given, this lists all entries in the current
			database. If a specific directory is given, this lists all entries 
			within the specified directory.
		
	EXAMPLE
		The following example demonstrates the editing of an entry
		
			spad edit /login/social/facebook
	
		The following example demonstrates the exporting of an active database
		
			spad export
			
		The following example demonstrates the inserting of an entry
	
			spad insert /login/social/facebook
			
		The following example demonstrates the removal of an entry
		
			spad remove /login/social/facebook
			
		The following example demonstrates the removal of multiple entries
		
			spad remove /login/
	
		The following example demonstrates the listing of all entries in the 
		active database
	
			spad show
		OR
			spad list
			
		The following example demonstrates the listing of entries within a specific
		directory
		
			spad show /login/social/"
}

######
# MAIN
######

if [ ! -d ~/.spad-errors/ ]; then
	mkdir ~/.spad-errors/
	touch ~/.spad-errors/log.txt
fi

case "$OPTION" in
	"edit" | "EDIT")
		check_for_entry
		edit
		;;
	"export" | "EXPORT")
    	printf "Exporting...\n"
    	export_db
    	;;
	"insert" | "INSERT")
		check_for_entry 
		insert_test
		;;
	"remove" | "REMOVE" | "rm" | "RM")
		remove
		;;
	"show" | "SHOW" | "list" | "LIST")
		show
		;;
	"help" | "HELP" | "-h" | "-H" | "--help" | "--HELP")
		usage | less
		;;
	*)
		usage | less
		;;
esac
